先前介紹的 fuzzer 如果沒有特別說明,基本上目標都是執行在 userspace 的程式,然而當 fuzzing 這個主題越來越熱門,開始有研究人員思考是否可以把這個概念實作在不同層級的目標,因為只要目標有辦法餵入輸入並取得 feedback (也許不限於 coverage),就能透過 fuzzer 逐步調整 input,讓目標執行到更廣更深的處理,同時先前研究的優化方法也能重新使用。在這個概念上,針對各種會需要執行程式,並且有辦法得到輸出的目標,都能嘗試接上 fuzzer 自動化找程式漏洞,例如 IOT fuzzer、firmware fuzzer 等各式各樣的 fuzzer,也包含這幾天要介紹的 OS fuzzer (kernel fuzzer) 與 hypervisor fuzzer,而 OS 又因為大多數的情況一定會用到,因此 OS fuzzer 的研究又特別熱門。
如果將 OS 視為一個 codebase 很大的程式,撇開 interrupt handler 那種基礎機制不說,程式的輸入就是來自 userspace 的 system call,輸出直觀來看就是 return code,代表有沒有成功執行。
如果將 hypervisor 視為目標,那輸入基本上就是在虛擬機中使用 PIO 或 MMIO 對模擬的硬體設備做存取,輸出就是看硬體設備暫存器所存放的回傳值。
OS fuzzer 泛指以 OS 為 fuzzing 對象的 fuzzer,並且 OS 不限於 Linux,其他像是以 Windows、FreeBSD 為目標的 fuzzer 也算在內,不過這邊基本上只會介紹 Linux fuzzer。在我的知識範圍中,最著代表性的兩個 Linux kernel fuzzer 分別是 kAFL 與 syzkaller,兩者都是以 Linux kernel 為目標 (雖然現在也支援其他作業系統),前者全名為 kernel-AFL,從名字就能知道它的重要性;後者為 google 開發的 fuzzing 框架,具有效能不差、好部署、資訊完全、客製化方便等優點,成為了目前 Linux kernel fuzzer 的龍頭。
雖然現在直接 google 搜尋 "linux kernel fuzzer",大概有一半的結果都與 syzkaller 有關,但稍微推算一下時間,kAFL 應該是早於 syzkaller 開始,並在 OS fuzzer 討論初期為相較成熟的 fuzzer。接下來會介紹 kAFL 使用到的機制與實作方式,一開始以論文 kAFL: Hardware-Assisted Feedback Fuzzing for OS Kernels 介紹整個框架,而後透過原始碼來深入了解內部運作。
kAFL 為 2017 年發表論文,因此在 2016 年時應該就實作的差不多了,反之 syzkaller 雖然在 2016 年被提出來,但到了 2018 年有較為成熟的框架。
可以將整個 kernel fuzzing 的執行流程拆成下面幾個部分討論:
與先前所介紹的 fuzzing 知識結合,能提出一些關鍵問題以及可能解法:
read()
會需要合法的 file descriptor,如果直接傳入記憶體位址或是 fd 非法都會失敗首先 kAFL 一共使用到以下兩個主要的機制來建構 fuzzing 環境,而下方條列也對各機制做介紹:
對於沒有 hypervisor 相關知識的讀者,在此做一些基本的介紹。
虛擬化技術一開始只是因為過去硬體太貴,所以為了最大化硬體資源,有人想到是否可以在電腦裡面再開一台電腦,這樣如果需要使用兩台電腦的環境,就不用物理上再買另一台電腦了。隨著技術的開發,QEMU (Quick EMUlator) 成功做到在原本的作業系統上,以 userspace 的程式模擬運行另一個作業系統,這也稱作 full-system emulation。雖然能成功運行,但代價就是效能上面的不足,因為原本 native 環境也許只是一行 instruction 能做到的事情,但透過模擬執行就可能要數百數千行 instruction,因此一些 CPU 廠商就開始設計用硬體的方式執行虛擬環境,所以有了 Intel-VX 以及 AMD-V 的出現。此外 arm 指令集也能透過 EL2 的相關設定與操作,建置虛擬機的執行環境,細節請參考 KVM/ARM: The Design and Implementation of the Linux ARM Hypervisor。
上述的虛擬化技術只是淺層皮毛,實際上有非常多細節與機制沒有介紹到,不過做 overview 已經算足夠了。接下來介紹一些虛擬化技術的名詞定義:
syscall
的定位,只是將 userspace 與 kernel 的角色換成 hypervisor 與 VM大量化簡後的 VM 與 VMM 互動如下圖:
hypercall
),則會發生 trap 到 host,之後將 trap 資訊轉給 hypervisor 做處理今天從設計者的角度分析 kernel fuzzer 的實作方式與挑戰,為虛擬化技術做了簡單的介紹,同時這些也是 kAFL 使用到的技術。明天會介紹論文提出的 kAFL 架構設計,並再透過 2~3 天的時間介紹原始碼,深入了解實作方法。